package com.jushu.storbox.service;

import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.StatFs;
import android.util.Log;

import com.jushu.storbox.ShareDriveApplication;
import com.jushu.storbox.callback.IDownloadCallback;
import com.jushu.storbox.constant.Constant;
import com.jushu.storbox.database.DAOFactory;
import com.jushu.storbox.database.IFileDao;
import com.jushu.storbox.entities.FileFolderInfo;
import com.jushu.storbox.entities.FileInfo;
import com.jushu.storbox.entities.FolderInfo;
import com.jushu.storbox.entities.ShareINode;
import com.jushu.storbox.filesystem.FileManagerFactory;
import com.jushu.storbox.filesystem.iFileManager;
import com.jushu.storbox.manager.DownloadTaskManager;
import com.jushu.storbox.task.tqueue.DownloadTask;
import com.jushu.storbox.util.CollectionUtils;
import com.jushu.storbox.util.DirectoryUtil;
import com.jushu.storbox.util.LogUtil;
import com.huawei.sharedrive.sdk.android.exception.ClientException;
import com.huawei.sharedrive.sdk.android.model.request.FolderBaseRequest;
import com.huawei.sharedrive.sdk.android.modelV2.request.Order;
import com.huawei.sharedrive.sdk.android.modelV2.request.ShareToMeRequestV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.FileInfoResponseV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.FolderListResponseV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.FolderResponse;
import com.huawei.sharedrive.sdk.android.modelV2.response.INodeShareV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.ShareResourceV2;
import com.huawei.sharedrive.sdk.android.serviceV2.FileClientV2;
import com.huawei.sharedrive.sdk.android.serviceV2.FolderClientV2;
import com.huawei.sharedrive.sdk.android.serviceV2.ShareClientV2;
import com.huawei.sharedrive.sdk.android.util.StringUtil;

/**
 * 
 * File operate util
 * 
 */
public class FileHelper
{
    
    /** FileHelper TAG */
    private static final String TAG = "FileHelper";
    
    /** FileHelper context */
    // private static Context context;
    
    /**
     * FileHelper construct function
     */
    public FileHelper()
    {
        super();
    }
    
    /**
     * update File List
     * 
     * @param folerListResponse
     * @return 
     */
    public static List<FileFolderInfo> convertFileRemoteToLocal(FolderListResponseV2 folerListResponse)
    {
        List<FileFolderInfo> fileList = new ArrayList<FileFolderInfo>();
        if (CollectionUtils.isEmpty(folerListResponse.getFiles()))
        {
            return fileList;
        }
        for (FileInfoResponseV2 fileInfoResponse : folerListResponse.getFiles())
        {
            FileFolderInfo fileInformation = new FileFolderInfo();
            fileInformation.setName(fileInfoResponse.getName());
            fileInformation.setContentCreatedAt(fileInfoResponse.getContentCreatedAt());
            fileInformation.setContentModifiedAt(fileInfoResponse.getContentModifiedAt());
            fileInformation.setCreatedAt(fileInfoResponse.getCreatedAt());
            fileInformation.setCreatedBy(fileInfoResponse.getCreatedBy());
            fileInformation.setEncrypt(fileInfoResponse.isEncrypt());
            fileInformation.setId(fileInfoResponse.getId());
            fileInformation.setMd5(fileInfoResponse.getMd5());
            fileInformation.setModifiedAt(fileInfoResponse.getModifiedAt());
            fileInformation.setModifiedBy(fileInfoResponse.getModifiedBy());
            fileInformation.setOwnerBy(fileInfoResponse.getOwnerBy());
            fileInformation.setSharedOwnerId(fileInfoResponse.getOwnerBy());
            fileInformation.setParent(fileInfoResponse.getParent());
            fileInformation.setSha1(fileInfoResponse.getSha1());
            fileInformation.setShare(fileInfoResponse.isShare());
            fileInformation.setSharelink(fileInfoResponse.isSharelink());
            fileInformation.setSize(fileInfoResponse.getSize());
            fileInformation.setStatus(fileInfoResponse.getStatus());
            fileInformation.setSync(fileInfoResponse.isSync());
            fileInformation.setType(fileInfoResponse.getType());
            fileInformation.setVersion(fileInfoResponse.getVersion());
            fileInformation.setIsFile(1);
            fileInformation.setThumbnailURL(fileInfoResponse.getThumbnailURL());
            fileList.add(fileInformation);
        }
        return fileList;
    }
    
    /**
     * update File&Folder List
     * 
     * @param folerListResponse
     * @return 
     */
    public static List<FileFolderInfo> convertFolderRemoteToLocal(FolderListResponseV2 folerListResponse)
    {
        List<FileFolderInfo> fileFolderList = new ArrayList<FileFolderInfo>();
        if (CollectionUtils.isEmpty(folerListResponse.getFolders()))
        {
            return fileFolderList;
        }
        for (FolderResponse folderResponse : folerListResponse.getFolders())
        {
            FileFolderInfo fileInformation = new FileFolderInfo();
            fileInformation.setName(folderResponse.getName());
            fileInformation.setContentCreatedAt(folderResponse.getContentCreatedAt());
            fileInformation.setContentModifiedAt(folderResponse.getContentModifiedAt());
            fileInformation.setCreatedAt(folderResponse.getCreatedAt());
            fileInformation.setCreatedBy(folderResponse.getCreatedBy());
            fileInformation.setEncrypt(folderResponse.getIsEncrypt());
            fileInformation.setId(folderResponse.getId());
            fileInformation.setModifiedAt(folderResponse.getModifiedAt());
            fileInformation.setModifiedBy(folderResponse.getModifiedBy());
            fileInformation.setOwnerBy(folderResponse.getOwnerBy());
            fileInformation.setSharedOwnerId(folderResponse.getOwnerBy());
            fileInformation.setParent(folderResponse.getParent());
            fileInformation.setShare(folderResponse.getIsShare());
            fileInformation.setSize(folderResponse.getSize());
            fileInformation.setStatus(folderResponse.getStatus());
            fileInformation.setSync(folderResponse.getIsSync());
            fileInformation.setType(folderResponse.getType());
            fileInformation.setIsFile(0);
            fileFolderList.add(fileInformation);
        }
        return fileFolderList;
    }
    
    /**
     * get folder List from server
     * 
     * @param folerListResponse 
     * @return 
     */
    public static List<FileFolderInfo> getFolderFromServer(FolderListResponseV2 folerListResponse)
    {
        List<FileFolderInfo> fileFolderList = new ArrayList<FileFolderInfo>();
        for (FolderResponse folderResponse : folerListResponse.getFolders())
        {
            FileFolderInfo fileInformation = new FileFolderInfo();
            fileInformation.setName(folderResponse.getName());
            fileInformation.setContentCreatedAt(folderResponse.getContentCreatedAt());
            fileInformation.setContentModifiedAt(folderResponse.getContentModifiedAt());
            fileInformation.setCreatedAt(folderResponse.getCreatedAt());
            fileInformation.setCreatedBy(folderResponse.getCreatedBy());
            fileInformation.setEncrypt(folderResponse.getIsEncrypt());
            fileInformation.setId(folderResponse.getId());
            fileInformation.setModifiedAt(folderResponse.getModifiedAt());
            fileInformation.setModifiedBy(folderResponse.getModifiedBy());
            fileInformation.setOwnerBy(folderResponse.getOwnerBy());
            fileInformation.setSharedOwnerId(folderResponse.getOwnerBy());
            fileInformation.setParent(folderResponse.getParent());
            fileInformation.setShare(folderResponse.getIsShare());
            fileInformation.setSize(folderResponse.getSize());
            fileInformation.setStatus(folderResponse.getStatus());
            fileInformation.setSync(folderResponse.getIsSync());
            fileInformation.setType(folderResponse.getType());
            fileInformation.setIsFile(0);
            fileFolderList.add(fileInformation);
        }
        return fileFolderList;
    }
    
    /**
     * @param fileName 
     * @return 
     */
    public static String getFileType(String fileName)
    {
        String fileType = "";
        if (StringUtil.isBlank(fileName))
        {
            return fileType;
        }
        if (fileName.contains("."))
        {
            int startIndex = fileName.lastIndexOf(".");
            fileType = fileName.substring(startIndex, fileName.length());
        }
        return fileType;
    }
    
    /**
     * @param fileS double
     * @return String
     */
    public static String formatFileSize(double fileS)
    {
        DecimalFormat df = new DecimalFormat("#.0");
        String fileSizeString = "";
        if (fileS <= 0)
        {
            fileSizeString = df.format((double) 0) + "B";
        }
        else if (fileS < 1024)
        {
            fileSizeString = df.format((double) fileS) + "B";
        }
        else if (fileS < 1048576)
        {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        }
        else if (fileS < 1073741824)
        {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        }
        else
        {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }
    
    /**
     * getFileCount(b/kb/mb/gb) 
     * 
     * @param folderPath String
     * @return int
     */
    public int getFileCount(String folderPath)
    {
        File f = new File(folderPath);
        int size = 0;
        File flist[] = f.listFiles();
        size = flist.length;
        for (int i = 0; i < flist.length; i++)
        {
            if (flist[i].isDirectory())
            {
                size = size + getFileCount(flist[i].getAbsolutePath());
                size--;
            }
        }
        return size;
    }
    
    /**
     * @param desc boolean
     * @param limite int
     * @param offset int
     * @param orderBy String
     * @return List<INodeShare>
     * @throws ClientException
     */
    public static List<INodeShareV2> getSharedList(String desc, int limite, int offset, String orderBy)
        throws ClientException
    {
        ShareToMeRequestV2 request = new ShareToMeRequestV2();
        request.setLimit(limite);
        request.setOffset(offset);
        
        List<Order> orderList = new ArrayList<Order>();
        Order order = new Order();
        order.setField(orderBy);
        order.setDirection(desc);
        orderList.add(order);
        request.setOrder(orderList);
        
        ShareResourceV2 response = ShareClientV2.getInstance()
            .listShareResourceToMe(ShareDriveApplication.getInstance().getAuthorization(), request);
        
        List<INodeShareV2> list = new ArrayList<INodeShareV2>();
        if (null != response)
        {
            list = response.getContents();
        }
        return list;
    }
    
    /**
     * @param shareList List<INodeShare>
     * @return ArrayList<FileInformation>
     */
    private static ArrayList<FileFolderInfo> getSharedList(List<INodeShareV2> shareList)
    {
        ArrayList<FileFolderInfo> list = new ArrayList<FileFolderInfo>();
        if (null != shareList)
        {
            for (int i = 0; i < shareList.size(); i++)
            {
                INodeShareV2 iNodeShare = shareList.get(i);
                FileFolderInfo fileInformation = new ShareINode();
                fileInformation.valueOf(iNodeShare);
                list.add(fileInformation);
            }
        }
        return list;
    }
    
    /**
     * @param desc boolean
     * @param limite int
     * @param offset int
     * @param orderBy String
     * @return ArrayList<FileInformation>
     * @throws ClientException
     */
    public static ArrayList<FileFolderInfo> getSharedResource(String desc, int limite, int offset,
        String orderBy) throws ClientException
    {
        List<INodeShareV2> shareList = getSharedList(desc, limite, offset, orderBy);
        ArrayList<FileFolderInfo> list = getSharedList(shareList);
        return list;
    }
    
    /**
     * @return
     */
    public static boolean isFileUpdate(Context context, List<FileInfoResponseV2> serverList,
        List<FileInfo> clientList)
    {
        if (serverList.isEmpty() && clientList.isEmpty())
        {
            return false;
        }
        if (serverList.size() != clientList.size())
        {
            return true;
        }
        
        for (FileInfoResponseV2 firServer : serverList)
        {
            FileInfo currentFile = null;
            for (FileInfo firClient : clientList)
            {
                if (!firServer.getId().equals(firClient.getId()))
                {
                    continue;
                }
                currentFile = firClient;
                if (!currentFile.isSync())
                {
                    return true;
                }

                if (isFileUpdate(context, firServer, firClient))
                {
                    LogUtil.i(TAG, "serverList  getSha1 not equalaaaaaaaaaa");
                    return true;
                }
            }
            if(currentFile == null){
            	return true;
            }
            
        }
        return false;
    }
    
    /**
     * @return
     */
    public static boolean isFolderUpdate(Context context, List<FolderResponse> serverList,
        List<FolderInfo> clientList)
    {
//        if (CollectionUtils.isEmpty(serverList) && CollectionUtils.isEmpty(clientList))
//        {
//            return false;
//        }
//        if (serverList.size() != clientList.size())
//        {
//            return true;
//        }
//        
//        for (FolderResponse frServer : serverList)
//        {
//            FolderInfo currentFolder = null;
//            for (FolderInfo localFolder : clientList)
//            {
//                if (!frServer.getId().equals(localFolder.getId()))
//                {
//                    continue;
//                }
//                currentFolder = localFolder;
//                if (frServer.getModifiedAt() != localFolder.getModifiedAt())
//                {
//                    return true;
//                }
//                if (!frServer.getName().equals(localFolder.getName()))
//                {
//                    return true;
//                }
//            }
//            if (currentFolder != null && !currentFolder.isSync())
//            {
//                return true;
//            }
//        }
        return false;
    }
    
    /**
     * @return
     */
    public static boolean compareServiceClientFolder(Context context, List<FolderResponse> serverList,
        List<FolderInfo> clientList, String ownerId, String folderId)
    {
        boolean isChange = false;
        
        if (CollectionUtils.isEmpty(serverList) && CollectionUtils.isEmpty(clientList))
        {
            isChange = false;
            return isChange;
        }

        FolderInfo parentFolder = DAOFactory.instance(context).getFolderDao().getFolderById(ownerId, folderId);
        
        for (FolderResponse frServer : serverList)
        {
            boolean isFolderUpdate = false;
            FolderInfo currentFolder = null;
            for (FolderInfo localFolder : clientList)
            {
                if (!frServer.getId().equals(localFolder.getId()))
                {
                    continue;
                }
                currentFolder = localFolder;
                if (!frServer.getName().equals(localFolder.getName()))
                {
                    isFolderUpdate = true;
                    break;
                }
                if (frServer.getModifiedAt() != localFolder.getModifiedAt())
                {
                    isFolderUpdate = true;
                    break;
                }
                break;
            }
            if (isFolderUpdate)
            {
                // isChange = true;
                DAOFactory.instance(context).getFolderDao().updateFolder(frServer);
            }
            if (currentFolder == null)
            {
            	FolderInfo local = DAOFactory.instance(context).getFolderDao().getFolderById(frServer);
            	if(local == null) {
            		DAOFactory.instance(context).getFolderDao().insertFolder(frServer, 0);
            	} else {
            		DAOFactory.instance(context).getFolderDao().updateFolder(frServer);
            	}
                isChange = false;
//                DAOFactory.instance(context).getFolderDao().insertOrUpdateFolder(frServer, context);
            }
            
            if(parentFolder != null && parentFolder.isSync())
            {
            	//this logic is error?
            	 DAOFactory.instance(context).getFileDao().
            	 updateSyncStatus(frServer.getOwnerBy(), frServer.getId(), Constant.DOWNLOAD_STATUS_CACHE_DB);
            }
        }
        
        for (FolderInfo localFolder : clientList)
        {
            boolean isExist = false;
            for (FolderResponse frServer : serverList)
            {
                if (frServer.getId().equals(localFolder.getId()))
                {
                    isExist = true;
                    break;
                }
            }
            if (!isExist)
            {
                isChange = false;
                boolean serverRemoved = true;
                try {
        			FolderBaseRequest request = new FolderBaseRequest();
        	        request.setFolderID(localFolder.getId());
        	        request.setAuthorization( ShareDriveApplication.getInstance().getAuthorization());
        	        request.setOwnerID(ShareDriveApplication.getInstance().getWnerID());
					FolderResponse serverItemInfo = FolderClientV2.getInstance().getFolderInfo(request);
					if(serverItemInfo != null){
						DAOFactory.instance(context).getFolderDao().updateFolder(serverItemInfo);
						serverRemoved = false;
					}
					
				} catch (ClientException e) {
					Log.e("file removed at server:", localFolder.getId());
				}
        		if(serverRemoved){
        			ServiceFactory.instance(context)
                    .getLocalFolderService()
                    .deleteFolderAndChild(localFolder);
        		}
            }
        }
        return isChange;
    }
    
    /**
     * @return
     */
    public static boolean compareShareServiceClientFolder(Context context, List<FolderResponse> serverList,
        List<FolderInfo> clientList, String defaultId)
    {
        boolean isChange = false;
        if (CollectionUtils.isEmpty(serverList) && CollectionUtils.isEmpty(clientList))
        {
            isChange = false;
            return isChange;
        }
        if (CollectionUtils.isEmpty(serverList))
        {
            for (FolderInfo localFolder : clientList)
            {
                ServiceFactory.instance(context)
                    .getLocalShareFolderService()
                    .deleteFolderAndChild(localFolder.getId(), localFolder.getOwnerBy());
            }
            isChange = true;
            return isChange;
        }
        for (FolderResponse frServer : serverList)
        {
            boolean isFolderUpdate = false;
            FolderInfo currentFolder = null;
            for (FolderInfo localFolder : clientList)
            {
                if (!frServer.getId().equals(localFolder.getId()))
                {
                    continue;
                }
                currentFolder = localFolder;
                if (frServer.getModifiedAt() != localFolder.getModifiedAt())
                {
                    isFolderUpdate = true;
                    break;
                }
                if (!frServer.getName().equals(localFolder.getName()))
                {
                    isFolderUpdate = true;
                    break;
                }
                if (frServer.getModifiedAt() != localFolder.getModifiedAt())
                {
                    isFolderUpdate = true;
                    break;
                }
            }
            if (isFolderUpdate)
            {
                DAOFactory.instance(context).getShareFolderDao().updateFolder(frServer, defaultId);
                isChange = true;
            }
            if (currentFolder == null)
            {
                ServiceFactory.instance(context)
                    .getLocalShareFolderService()
                    .insertFolder(frServer, defaultId);
                isChange = true;
            }
        }
        
        for (FolderInfo localFolder : clientList)
        {
            boolean isExist = false;
            for (FolderResponse frServer : serverList)
            {
                if (frServer.getId().equals(localFolder.getId()))
                {
                    isExist = true;
                    break;
                }
            }
            if (!isExist)
            {
                ServiceFactory.instance(context)
                    .getLocalShareFolderService()
                    .deleteFolderAndChild(localFolder.getId(), localFolder.getOwnerBy());
                isChange = true;
            }
        }
        return isChange;
    }
    
    /**
     * @return
     */
    public static boolean compareServiceClientFile(Context context, List<FileInfoResponseV2> serverList,
        List<FileInfo> clientList, String ownerId, String folderId)
    {
        boolean isChange = false;
        if (CollectionUtils.isEmpty(serverList) && CollectionUtils.isEmpty(clientList))
        {
            return isChange;
        }
//        if (CollectionUtils.isEmpty(serverList))
//        {
//            for (FileInfo localFolder : clientList)
//            {
//                ServiceFactory.instance(context).getLocalFileService().deleteFile(localFolder.getId());
//            }
//            return isChange;
//        }
        boolean FileContentIsChanged = false;
        boolean nameIsUpdate = false;
        boolean isFileUpate = false;
        String oldFilePath = null;
        String newFilePath = null;

        FolderInfo folder = DAOFactory.instance(context).getFolderDao().getFolderById(ownerId, folderId);

        iFileManager mdmTools = FileManagerFactory
				.getFileManager(context);
        for (FileInfoResponseV2 frServer : serverList)
        {
        	FileContentIsChanged = false;
        	nameIsUpdate = false;
            isFileUpate = false;
            FileInfo currentFile = null;
            for (FileInfo localFile : clientList)
            {
                if (!frServer.getId().equals(localFile.getId()))
                {
                    continue;
                }
                currentFile = localFile;
                if (!frServer.getName().equals(localFile.getName()))
                {
                    isFileUpate = true;
                    nameIsUpdate = true;
                    oldFilePath = DirectoryUtil.generateFileDownloadPath(context, localFile.getOwnerBy(), localFile.getId(), localFile.getName());
                }
                if (!fileContentEquals(frServer,localFile))
                {
                    isFileUpate = true;
                    if(localFile.isSync())
                    {
                    	FileContentIsChanged = true;
                    }
                    oldFilePath = DirectoryUtil.generateFileDownloadPath(context, localFile.getOwnerBy(), localFile.getId(), localFile.getName());
                }
                if (frServer.getModifiedAt() != localFile.getModifiedAt())
                {
                    isFileUpate = true;
                }
                break;
            }
                        
            if (isFileUpate)
            {
                LogUtil.i("~~","server update file item" + frServer.getName());
                DAOFactory.instance(context).getFileDao().updateFile(frServer, false, false);
                if(FileContentIsChanged)
                {
                	LogUtil.i("~~","server update file content" +currentFile.getName());
                    mdmTools.deleteFile(oldFilePath);
					DirectoryUtil.deleteFileThumbnailPath(context,
						currentFile.getOwnerBy(), currentFile.getId(),
						currentFile.getName());
                	DAOFactory.instance(context).getFileDao().
                		updateTransStatus(currentFile, Constant.DOWNLOAD_NON_UPDATE_DB);
                	isChange = true;
                }
                if (nameIsUpdate)
                {
            		DAOFactory.instance(context).getFileDao()
        				.updateLocalPath(frServer, newFilePath);
                	LogUtil.i("~~","server update file item'name: old name: " +currentFile.getName()+ "new name: "+ frServer.getName());
                    newFilePath = DirectoryUtil.generateFileDownloadPath(context, frServer.getOwnerBy(), frServer.getId(), frServer.getName());
                    mdmTools.rename(oldFilePath, newFilePath);
                    DirectoryUtil.renameThumbnailFile(context, 
                    		currentFile.getOwnerBy(),currentFile.getId(), currentFile.getName(), frServer.getName());
                }
                
            }
            if (currentFile == null)
            {
            	LogUtil.i("~~","server \"add\" new file item" + frServer.getName());
                FileInfo fileInfo = DAOFactory.instance(context).getFileDao().getFile(frServer);
                if (null != fileInfo)
                {
                    DAOFactory.instance(context).getFileDao().updateFile(frServer, false, false);
                    
                	LogUtil.i("~~","server move file item: old-> " +fileInfo.getParent()+"new-> "+ frServer.getParent());
                    oldFilePath = DirectoryUtil.generateFileDownloadPath(context, fileInfo.getOwnerBy(), fileInfo.getId(), fileInfo.getName());
                    newFilePath = DirectoryUtil.generateFileDownloadPath(context, frServer.getOwnerBy(), frServer.getId(), frServer.getName());
                	
                	if(!fileContentEquals(frServer,fileInfo)) 
                	{
                		LogUtil.i("~~","server move and update file content: " +fileInfo.getName());
                        mdmTools.deleteFile(oldFilePath);
						DirectoryUtil.deleteFileThumbnailPath(context,
							fileInfo.getOwnerBy(), fileInfo.getId(),
							fileInfo.getName());
                		DAOFactory.instance(context).getFileDao().
   	            	 		updateTransStatus(fileInfo, Constant.DOWNLOAD_NON_UPDATE_DB);
                		isChange = true;
                	}
                	
                	if(!frServer.getName().equals(fileInfo.getName()))
                	{
                		DAOFactory.instance(context).getFileDao()
            				.updateLocalPath(frServer, newFilePath);
                		LogUtil.i("~~","server move and update file item'name: old name: " +fileInfo.getName()+ "new name: "+ frServer.getName());
                        mdmTools.rename(oldFilePath, newFilePath);
		                DirectoryUtil.renameThumbnailFile(context, 
		                    fileInfo.getOwnerBy(),fileInfo.getId(), fileInfo.getName(), frServer.getName());
                    }
                	
                }
                else
                {
                	LogUtil.i("~~","server add new file item: " +frServer.getName());
                    DAOFactory.instance(context).getFileDao().insertFile(frServer);
                    isChange = true;
                }
                if(folder != null && folder.isSync())
	            {
	            	 DAOFactory.instance(context).getFileDao().
	            	 	updateSyncStatus(frServer, Constant.DOWNLOAD_STATUS_CACHE_DB);
	            }
            }
        }
        
        for (FileInfo localFile : clientList)
        {
            boolean isExist = false;
            for (FileInfoResponseV2 frServer : serverList)
            {
                if (frServer.getId().equals(localFile.getId()))
                {
                    isExist = true;
                    break;
                }
            }
            if (!isExist)
            {
				boolean serverRemove = true;
				try 
				{
					LogUtil.i("~~","server \"delete\" file item: " +localFile.getName());
                    FileInfoResponseV2 serverItemInfo = FileClientV2
						.getInstance().getFileInfo(
						ShareDriveApplication.getInstance().getWnerID(),
						localFile.getId(),
						ShareDriveApplication.getInstance().getAuthorization());
					if (serverItemInfo != null) 
					{
	                    DAOFactory.instance(context).getFileDao().updateFile(serverItemInfo, false, false);
	                    
						oldFilePath = DirectoryUtil.generateFileDownloadPath(context, localFile.getOwnerBy(), localFile.getId(), localFile.getName());
	                    newFilePath = DirectoryUtil.generateFileDownloadPath(context, serverItemInfo.getOwnerBy(), serverItemInfo.getId(), serverItemInfo.getName());

						if(!fileContentEquals(serverItemInfo,localFile)) 
						{
							LogUtil.i("~~","server move and update file content");
		                    mdmTools.deleteFile(oldFilePath);
							DirectoryUtil.deleteFileThumbnailPath(context,
								localFile.getOwnerBy(), localFile.getId(),
								localFile.getName());
							isChange = true;
						}
						
	                	if(!serverItemInfo.getName().trim().equals(localFile.getName().trim()))
	                	{
							DAOFactory.instance(context).getFileDao()
									.updateLocalPath(serverItemInfo, newFilePath);
	                		LogUtil.i("~~","server move and rename file item:new name->: " +serverItemInfo.getName());
		                    mdmTools.rename(oldFilePath, newFilePath);
		                    DirectoryUtil.renameThumbnailFile(context, localFile.getOwnerBy(),
		                    	localFile.getId(),localFile.getName(), serverItemInfo.getName());
	                    }
	                	
						serverRemove = false;
					}

				} catch (ClientException e) {
					Log.e("file removed at server:", localFile.getId());
				}
				if (serverRemove) {
					LogUtil.i("~~","server delete file item!");
                    mdmTools.deleteFile(localFile.getLoctPath());
					DirectoryUtil.deleteFileThumbnailPath(context,
						localFile.getOwnerBy(), localFile.getId(),
						localFile.getName());
					ServiceFactory.instance(context).getLocalFileService()
							.deleteFileVirtual(localFile);
				}
			}
        }
        return isChange;
    }
    
    /**
     * @return
     */
    public static boolean compareShareServiceClientFile(Context context, List<FileInfoResponseV2> serverList,
        List<FileInfo> clientList)
    {
        boolean isChange = false;
        if (CollectionUtils.isEmpty(serverList) && CollectionUtils.isEmpty(clientList))
        {
            isChange = false;
            return isChange;
        }
        if (CollectionUtils.isEmpty(serverList))
        {
            for (FileInfo localFolder : clientList)
            {
                ServiceFactory.instance(context)
                    .getLocalShareFileService()
                    .deleteFile(localFolder.getId(), localFolder.getOwnerBy());
            }
            isChange = true;
            return isChange;
        }
        for (FileInfoResponseV2 frServer : serverList)
        {
            boolean isFileUpate = false;
            FileInfo currentFile = null;
            for (FileInfo localFile : clientList)
            {
                if (!frServer.getId().equals(localFile.getId()))
                {
                    continue;
                }
                currentFile = localFile;
                if (frServer.getModifiedAt() != localFile.getModifiedAt())
                {
                    isFileUpate = true;
                    break;
                }
                if (!frServer.getName().equals(localFile.getName()))
                {
                    isFileUpate = true;
                    break;
                }
                if (!fileContentEquals(frServer,localFile))
                {
                    isFileUpate = true;
                    break;
                }
                if (frServer.getModifiedAt() != localFile.getModifiedAt())
                {
                    isFileUpate = true;
                    break;
                }
            }
            if (isFileUpate)
            {
                DAOFactory.instance(context).getShareFileDao().updateFile(frServer, true);
                // isChange = true;
            }
            
            if (currentFile == null)
            {
                DAOFactory.instance(context).getShareFileDao().insertFile(frServer);
                isChange = true;
            }
        }
        
        for (FileInfo localFile : clientList)
        {
            boolean isExist = false;
            for (FileInfoResponseV2 frServer : serverList)
            {
                if (frServer.getId().equals(localFile.getId()))
                {
                    isExist = true;
                    break;
                }
            }
            if (!isExist)
            {
                iFileManager mdmTools = FileManagerFactory.getFileManager(context);
                Log.e("~~", "localFile.getLoctPath():" + localFile.getLoctPath());
                mdmTools.deleteFile(localFile.getLoctPath());
                DAOFactory.instance(context)
                    .getShareFileDao()
                    .deleteFile(localFile.getId(), localFile.getOwnerBy());
                isChange = true;
            }
        }
        return isChange;
    }
    
    /**
     * @return
     */
    public static boolean compareServiceClientINode(Context context, List<INodeShareV2> serverList,
        List<FileFolderInfo> clientList)
    {
        boolean isChanged = false;
        if (CollectionUtils.isEmpty(serverList) && CollectionUtils.isEmpty(clientList))
        {
            isChanged = false;
            return isChanged;
        }
        if (CollectionUtils.isEmpty(serverList))
        {
            for (FileFolderInfo localFolder : clientList)
            {
                // ServiceFactory.instance(context).getLocalFileService().deleteFile(localFolder.getId());
                DAOFactory.instance(context)
                    .getShareINodeDao()
                    .deleteFileOrFolder(localFolder.getId(), localFolder.getOwnerBy());
            }
            return true;
        }
        for (INodeShareV2 frServer : serverList)
        {
            Boolean isnew = true;
            boolean isFileUpate = false;
            
            String frNodeid = String.valueOf(frServer.getNodeId());
            String frOwnerId = String.valueOf(frServer.getOwnerId());
            if (null != clientList)
            {
                
                for (FileFolderInfo localFile : clientList)
                {
                    if (frNodeid.equals(localFile.getiNodeId()) && (frOwnerId.equals(localFile.getOwnerBy())))
                    {
                        isnew = false;
                        if (frServer.getModifiedAt() != localFile.getModifiedAt())
                        {
                            isFileUpate = true;
                            break;
                        }
                        if (!frServer.getName().equals(localFile.getName()))
                        {
                            isFileUpate = true;
                            break;
                        }
                        if (frServer.getModifiedAt() != localFile.getModifiedAt())
                        {
                            isFileUpate = true;
                            break;
                        }
                        
                    }
                }
            }
            if (isFileUpate)
            {
                // DAOFactory.instance(context).getFileDao().updateFile(frServer);
                DAOFactory.instance(context).getShareINodeDao().updateFile(frServer, true);
                // isChanged = true;
            }
            if (isnew)
            {
                DAOFactory.instance(context).getShareINodeDao().insertFolderOrFile(frServer);
                isChanged = true;
            }
            if (null != clientList)
            {
                for (FileFolderInfo localFile : clientList)
                {
                    boolean isExist = false;
                    for (INodeShareV2 frServer2 : serverList)
                    {
                        String fr2Nodeid = String.valueOf(frServer2.getNodeId());
                        String fr2OwnerId = String.valueOf(frServer2.getOwnerId());
                        if ((fr2Nodeid.equals(localFile.getiNodeId()) && (fr2OwnerId.equals(localFile.getOwnerBy()))))
                        {
                            isExist = true;
                            break;
                        }
                    }
                    if (!isExist)
                    {
                        // DAOFactory.instance(context).getFileDao().deleteFile(localFile.getId());
                        DAOFactory.instance(context)
                            .getShareINodeDao()
                            .deleteFileOrFolder(localFile.getId(), localFile.getOwnerBy());
                        isChanged = true;
                    }
                }
            }
        }
        return isChanged;
    }
    
    public static void compareServiceClientFileAndDownload(Context context,
        List<FileInfoResponseV2> serverList, List<FileInfo> clientList, String folderID)
    {
        // FileHelper.compareServiceClientFile(context, serverList, clientList,
        // parentFolder, true);
        if (CollectionUtils.isEmpty(serverList) && CollectionUtils.isEmpty(clientList))
        {
            return;
        }
        if (CollectionUtils.isEmpty(serverList))
        {
            for (FileInfo localFolder : clientList)
            {
                ServiceFactory.instance(context).getLocalFileService().deleteFileVirtual(localFolder);
            }
            return;
        }
        boolean shouldUpdateFileContent = false;
        for (FileInfoResponseV2 frServer : serverList)
        {
        	shouldUpdateFileContent = false;
            boolean isFileUpate = false;
            FileInfo currentFile = null;
            for (FileInfo localFile : clientList)
            {
                if (!frServer.getId().equals(localFile.getId()))
                {
                    continue;
                }
                currentFile = localFile;
                if (!frServer.getName().equals(localFile.getName()))
                {
                    isFileUpate = true;
                }
                if (!fileContentEquals(frServer,localFile))
                {
                	shouldUpdateFileContent = true;
                    isFileUpate = true;
                }
                if (frServer.getModifiedAt() != localFile.getModifiedAt())
                {
                    isFileUpate = true;
                }
                break;
                
            }
            String path = DirectoryUtil.generateFileDownloadPath(context, frServer.getOwnerBy(), frServer.getId(), frServer.getName());
            if (isFileUpate)
            {
                DAOFactory.instance(context).getFileDao().updateFile(frServer, false, true);
            }
            if (currentFile == null)
            {
                FileInfo fileInfo = DAOFactory.instance(context).getFileDao().getFile(frServer);
                //move from other space
                if (null != fileInfo)
                {
                	//content is changed
                	if(!fileContentEquals(frServer,fileInfo)) {
                    	shouldUpdateFileContent = true;
                		DAOFactory.instance(context).getFileDao().updateFile(frServer, true, false);
                	}
                }
                else//real add new item
                {
                	shouldUpdateFileContent = true;
                    DAOFactory.instance(context).getFileDao().insertFile(frServer);
                }
                //set the new item's syncFlag to sync
                DAOFactory.instance(context).getFileDao().updateSyncStatus(frServer, Constant.DOWNLOAD_STATUS_CACHE_DB);
            }
            FileInfo fileInfo = DAOFactory.instance(context).getFileDao().getFile(frServer);
            if (!fileInfo.isSync() || fileInfo.getTransStatus() !=  Constant.DOWNLOAD_SUCCESS_UPDATE_DB|| 
            		shouldUpdateFileContent)
            {
                IDownloadCallback callback = new IDownloadCallback()
                {
                    
                    @Override
                    public void onSuccess()
                    {
                    }
                    
                    @Override
                    public void onStart()
                    {
                    }
                    
                    @Override
                    public void onProgress(int currentProgress, long currentSize, long maxSize)
                    {
                    }
                    
                    @Override
                    public void onFailure(Throwable t, int statusCode)
                    {
                    }

					@Override
					public void onStop() {
					}

					@Override
					public void onCanceled() {
					}

					@Override
					public void onDettach() {
					}
                };
                fileInfo.valueOf(frServer);
                DAOFactory.instance(context)
                    .getFileDao()
                    .updateSyncStatus(frServer, Constant.DOWNLOAD_STATUS_CACHE_DB);
                DAOFactory.instance(context).getFileDao().updateLocalPath(frServer, path);
                DownloadTaskManager.addTask(new DownloadTask(context, callback, fileInfo, true));
            }
        }
        for (FileInfo localFile : clientList)
        {
            boolean isExist = false;
            for (FileInfoResponseV2 frServer : serverList)
            {
                if (frServer.getId().equals(localFile.getId()))
                {
                    isExist = true;
                    break;
                }
            }
            if (!isExist)
            {
                Log.e("~~", "localFile.getLoctPath():" + localFile.getLoctPath());
                ServiceFactory.instance(context).getLocalFileService().deleteFileVirtual(localFile);
            }
        }
        
    }
    
    public static void compareServiceClientFolderAndDownload(Context context,
        List<FolderResponse> serverList, List<FolderInfo> clientList)
    {
        if (CollectionUtils.isEmpty(serverList) && CollectionUtils.isEmpty(clientList))
        {
            return;
        }
        if (CollectionUtils.isEmpty(serverList))
        {
            for (FolderInfo localFolder : clientList)
            {
                ServiceFactory.instance(context)
                    .getLocalFolderService()
                    .deleteFolderAndChild(localFolder);
            }
            return;
        }
        for (FolderResponse frServer : serverList)
        {
            boolean isFolderUpdate = false;
            FolderInfo currentFolder = null;
            for (FolderInfo localFolder : clientList)
            {
                if (!frServer.getId().equals(localFolder.getId()))
                {
                    continue;
                }
                currentFolder = localFolder;
                if (frServer.getModifiedAt() != localFolder.getModifiedAt())
                {
                    isFolderUpdate = true;
                    break;
                }
                if (!frServer.getName().equals(localFolder.getName()))
                {
                    isFolderUpdate = true;
                    break;
                }
                if (frServer.getModifiedAt() != localFolder.getModifiedAt())
                {
                    isFolderUpdate = true;
                    break;
                }
            }
            if (isFolderUpdate)
            {
                DAOFactory.instance(context).getFolderDao().updateFolder(frServer);
            }
            if (currentFolder == null)
            {
                FolderInfo fileInfo = DAOFactory.instance(context).getFolderDao().getFolderById(frServer);
                //move from other space
                if (null != fileInfo)
                {
                	//content is changed
                	DAOFactory.instance(context).getFolderDao().updateFolder(frServer);
                	//set the new item's syncFlag to sync
                    DAOFactory.instance(context).getFolderDao().updateSyncStatuc(frServer, Constant.DOWNLOAD_STATUS_CACHE_DB);
                }
                else//real add new item
                {
                    DAOFactory.instance(context).getFolderDao().insertFolder(frServer, Constant.DOWNLOAD_STATUS_CACHE_DB);
                }
            }
            else
            {
                ServiceFactory.instance(context)
                    .getLocalFolderService()
                    .updateSyncStatus(Constant.DOWNLOAD_STATUS_CACHE_DB, frServer.getOwnerBy(), frServer.getId());
            }
        }
        
        for (FolderInfo localFolder : clientList)
        {
            boolean isExist = false;
            for (FolderResponse frServer : serverList)
            {
                if (frServer.getId().equals(localFolder.getId()))
                {
                    isExist = true;
                    break;
                }
            }
            if (!isExist)
            {
                ServiceFactory.instance(context)
                    .getLocalFolderService()
                    .deleteFolderAndChild(localFolder);
            }
        }
        
    }
    
    /***
     * 
     * @param ownerId
     * @param request
     * @param authCode
     * @return
     * @throws ClientException
     */
    public static FileFolderInfo createFolder(FolderResponse folderResponse) throws ClientException
    {
        FileFolderInfo fileInformation = new FileFolderInfo();
        fileInformation.setName(folderResponse.getName());
        fileInformation.setContentCreatedAt(folderResponse.getContentCreatedAt());
        fileInformation.setContentModifiedAt(folderResponse.getContentModifiedAt());
        fileInformation.setCreatedAt(folderResponse.getCreatedAt());
        fileInformation.setCreatedBy(folderResponse.getCreatedBy());
        fileInformation.setEncrypt(folderResponse.getIsEncrypt());
        fileInformation.setId(folderResponse.getId());
        fileInformation.setModifiedAt(folderResponse.getModifiedAt());
        fileInformation.setModifiedBy(folderResponse.getModifiedBy());
        fileInformation.setOwnerBy(folderResponse.getOwnerBy());
        fileInformation.setSharedOwnerId(folderResponse.getOwnerBy());
        fileInformation.setParent(folderResponse.getParent());
        fileInformation.setShare(folderResponse.getIsShare());
        fileInformation.setSize(folderResponse.getSize());
        fileInformation.setStatus(folderResponse.getStatus());
        fileInformation.setSync(folderResponse.getIsSync());
        fileInformation.setType(folderResponse.getType());
        fileInformation.setVersion("");
        fileInformation.setIsFile(0);
        return fileInformation;
    }
    
    /**
     * get Using SDCard Size in device
     * 
     * @param context Context
     * @param pathDirectory String
     * @return double
     */
    public static double getUsingSDCardSize(Context context, String pathDirectory)
    {
        String[] sdcardSize = new String[2];
        double usingSize = 0;
        double totalSize = 0;
        try
        {
            File path = new File(pathDirectory);
            // File path = Environment.getExternalStorageDirectory();
            if (path.exists())
            {
                StatFs stat = new StatFs(path.getPath());
                double blockSize = stat.getBlockSize();
                double usingBlocks = stat.getAvailableBlocks();
                double totalBlocks = stat.getBlockCount();
                usingSize = usingBlocks * blockSize;
                totalSize = totalBlocks * blockSize;
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            e.printStackTrace();
        }
        return usingSize;
    }

	public static boolean isFileUpdate(Context context,
			FileInfoResponseV2 serverFileObj, FileFolderInfo localFileObj) {

		if (serverFileObj == null && localFileObj == null) {
			return false;
		}

		if (!serverFileObj.getId().equals(localFileObj.getId())) {
			return true;
		}
		
		IFileDao fileDao = DAOFactory.instance(context).getFileDao();
		
		if (serverFileObj.getModifiedAt() != localFileObj.getModifiedAt()) {
			fileDao.updateFile(serverFileObj, false, false);
		}
		
		if (!serverFileObj.getIdentity().equals(localFileObj.getLocalIdentity())) {
			LogUtil.i(TAG, "serverList  getSha1 not equalaaaaaaaaaa");
			localFileObj.setContentSyncState(Constant.SYNC_STATUS_FALSE);
			fileDao.updateLocalSaveState(localFileObj);
			localFileObj.notifyChange();
			return true;
		}
		
		return false;
	}
    
	private static boolean fileContentEquals(FileInfoResponseV2 server, FileInfo local){
		try{
			if(server.getMd5() != null){
				return server.getMd5().equals(local.getMd5());
			}else{
				return server.getSha1().equals(local.getSha1());
			}
		}catch(Exception e){
			LogUtil.e("File content compare exception: "+e.getMessage());
		}
		return true;
	}
	
	/***
     * 
     * @param ownerId
     * @param request
     * @param authCode
     * @return
     * @throws ClientException
     */
    public static FileFolderInfo createFolder(com.huawei.sharedrive.sdk.android.model.response.FolderResponse folderResponse) throws ClientException
    {
        FileFolderInfo fileInformation = new FileFolderInfo();
        fileInformation.setName(folderResponse.getName());
        fileInformation.setContentCreatedAt(folderResponse.getContentCreatedAt());
        fileInformation.setContentModifiedAt(folderResponse.getContentModifiedAt());
        fileInformation.setCreatedAt(folderResponse.getCreatedAt());
        fileInformation.setCreatedBy(folderResponse.getCreatedBy());
        fileInformation.setDescription(folderResponse.getDescription());
        fileInformation.setEncrypt(folderResponse.getIsEncrypt());
        fileInformation.setId(folderResponse.getId());
        fileInformation.setModifiedAt(folderResponse.getModifiedAt());
        fileInformation.setModifiedBy(folderResponse.getModifiedBy());
        fileInformation.setOwnerBy(folderResponse.getOwnerBy());
        fileInformation.setSharedOwnerId(folderResponse.getOwnerBy());
        fileInformation.setParent(folderResponse.getParent());
        fileInformation.setShare(folderResponse.getIsShare());
        fileInformation.setSize(folderResponse.getSize());
        fileInformation.setStatus(folderResponse.getStatus());
        fileInformation.setSync(folderResponse.getIsSync());
        fileInformation.setType(folderResponse.getType());
        fileInformation.setVersion(folderResponse.getVersion());
        fileInformation.setIsFile(0);
        return fileInformation;
    }
}
